//****************************************//
//    mCore.cpp 18012012                  //
//    Riku Maikola rpm@ac-mapa.org        //
//****************************************//
#include "mCore.h"

bool mCore::E(wxString COMMAND)
{
    ERR = _("");        //CLEAR
    int LOOPLIMIT=0;

    //TOKENIZER
    wxArrayString row = wxStringTokenize(COMMAND, wxT("\n"),wxTOKEN_STRTOK);
    wxArrayString T;

    size_t rp=-1;
    while(true)
    {
        rp++;
        if( row.GetCount()==rp )
            break;

        if(!ERR.Matches(_("")))
            break;

        bool IsNotExtFunc = true;

        P.clear();
        Parse( row.Item(rp) );
        if(P[0]==_("#") || P[0]==_("("))    //IS G code so.... print it there
        {
            CODE << row.Item(rp) << _("\n");
            continue;
        }
        EVA();

        T.clear();
        for(uint a=0; P.GetCount()>a;a++)
        {
            T.Add(P[a]);
        }
        if(T.GetCount()==0)
        {
             IsNotExtFunc = false;
            continue;


        }

        wxString token;
        token.clear();
        while(true)
        {
            if(T.GetCount()<1)break;
            if(T[0]==_("(") )
            {
                T.RemoveAt(0);
                break;
            }
            token << T[0];
            T.RemoveAt(0);
        }

        if(T[0]==_(")"))T.RemoveAt(0);

        //REMOVE FILLINGS for function calling
        for(int a=0; a<int(T.GetCount()); a++)
        {
            if(T[a] == _(",") || T[a] == _("(") || T[a] == _(")"))
            {
                T.RemoveAt(a);
                a--;
            }

            if(T[a] == _("/"))
                if(T[a+1] == _("/"))
                    T.RemoveAt(a,T.GetCount()-a);
        }
        if(token.Matches(_("//*")) )continue;    //comment no use

#include "functions/_if_list.h"

        if(IsNotExtFunc)CODE << row.Item(rp) << _("\n");
    }

    CODE.Replace(_(","),_("."));

    if(!ERR.Matches(_("")))
    {
        CODE.clear();
        CODE << _("err::") << ERR << _("\n");
    }
    return true;
};

//*****************************//
bool mCore::Names(wxString token)
{
    INFO = _("");              //clear command list
    //********************************//
    wxString match;
    for(size_t a=0; a<c_list.Count(); a++)
    {
        match.clear();
        match = c_list[a];
        match << _("(*");

        if( token.Matches(match))
        {
            wxTextFile code;
            match = _("docs/");
            match << c_list[a];

            if(code.Open(match))
            {
                INFO << code.GetFirstLine();
                {
                    while(!code.Eof())
                    {
                        INFO << code.GetNextLine();
                    }
                }
            }
            return true;
        }
        if( token.Cmp(  match  ) < 1)
            INFO << c_list[a] << _("</a><BR>");
    }
    return false;

};
//LOAD PROJECT
bool mCore::Load(wxString F)
{
   /* wxTextFile code;
    PATH = F;

    for(uint a=0; a<numImages; a++)
        I[a].Clear();
    if(code.Open(F))
    {
        if(code.GetFirstLine().Matches(_("MAICAM")))
        {
            while(!code.Eof())
            {
                wxString L = code.GetNextLine();
                if(L.Matches(_("<SCRIPT>")))
                {
                    SCRIPT.Clear();
                    while(true)
                    {
                        wxString O = code.GetNextLine();
                        if(O.Matches(_("</>")))break;
                        SCRIPT << O << _("\n");
                        if(code.Eof())break;
                    }
                    SCRIPT.Trim();
                    continue;
                }

                if(L.Matches(_("<CODE>")))
                {
                    CODE.Clear();
                    while(true)
                    {
                        wxString O = code.GetNextLine();
                        if(O.Matches(_("</>")))break;
                        CODE << O << _("\n");
                        if(code.Eof())break;
                    }
                    CODE.Trim();
                    continue;
                }

                if(L.Matches(_("<SETUP>")))
                {
                    SETUP.Clear();
                    while(true)
                    {
                        wxString O = code.GetNextLine();
                        if(O.Matches(_("</>")))break;
                        SETUP << O << _("\n");
                        if(code.Eof())break;
                    }
                    SETUP.Trim();
                    continue;
                }
                E(L);
            }
        }
    }
    else
        return FALSE;*/

    return true;
}

void mCore::Save(wxString file)
{
    wxTextFile code(file);
    code.AddLine(_("MAICAM"));

    wxArrayString R = wxStringTokenize(SCRIPT, wxT("\n"),wxTOKEN_STRTOK);
    code.AddLine(_("set_echo(SCRIPT)"));
    for(size_t a=0;a<R.Count();a++)code.AddLine( wxString::Format(_("e(%s)"),  R.Item(a).data() ) );

    R = wxStringTokenize(CODE, wxT("\n"),wxTOKEN_STRTOK);
    code.AddLine(_("set_echo(CODE)"));
    for(size_t a=0;a<R.Count();a++)code.AddLine( wxString::Format(_("e(%s)"),  R.Item(a).data() ) );

    R = wxStringTokenize(SETUP, wxT("\n"),wxTOKEN_STRTOK);
    code.AddLine(_("set_echo(SETUP)"));
    for(size_t a=0;a<R.Count();a++)code.AddLine( wxString::Format(_("e(%s)"),  R.Item(a).data() ) );

    //images
    for(uint a=0; a<numImages; a++)
    {
        if( I[a].ME.size()>0)code.AddLine( wxString::Format(_("set_image_number(%d)"),a));
        for(uint b=0; b<I[a].ME.size(); b++)
        {
            //LINE
            if(I[a].ME[b]->T()==e_Line)code.AddLine( wxString::Format(_("l(%1.15f,%1.15f,%1.15f,%1.15f)"),I[a].ME[b]->p1().x,I[a].ME[b]->p1().y,I[a].ME[b]->p2().x,I[a].ME[b]->p2().y));
            //ARC
            if(I[a].ME[b]->T()==e_Arc)code.AddLine( wxString::Format(_("a(%1.15f,%1.15f,%1.15f,%1.15f,%1.15f)"),I[a].ME[b]->cp().x,I[a].ME[b]->cp().y,I[a].ME[b]->a1,I[a].ME[b]->a2,I[a].ME[b]->r));
            //circle
            if(I[a].ME[b]->T()==e_Circle)code.AddLine( wxString::Format(_("c(%1.15f,%1.15f,%1.15f)"),I[a].ME[b]->cp().x,I[a].ME[b]->cp().y,I[a].ME[b]->r));
            //triangle
            if(I[a].ME[b]->T()==e_Triangle)code.AddLine( wxString::Format(_("t(%1.15f,%1.15f,%1.15f,%1.15f,%1.15f,%1.15f,%1.15f,%1.15f,%1.15f)"),

                                                                 I[a].ME[b]->p1().x, I[a].ME[b]->p1().y, I[a].ME[b]->p1().z,
                                                                 I[a].ME[b]->p2().x, I[a].ME[b]->p2().y, I[a].ME[b]->p2().z,
                                                                 I[a].ME[b]->p3().x, I[a].ME[b]->p3().y, I[a].ME[b]->p3().z

                                                                 ));

        }
        if(I[a].IsType()==m_Chain) code.AddLine( wxString::Format(_("chain()")));

    }
    //**********************//
    //**       Tools     **//
    //**********************//
    for(uint a=0; a<numTools; a++)
    {
        if(I[startToolPos+a].FileName.Len() > 0)
        {
            wxString save = wxString::Format(_("t_load(%d,\""),a);
            save << I[startToolPos+a].FileName;
            save << _("\")");
            code.AddLine(save);
        }
    }

    code.Create();
    code.Write();
    code.Close();

}

//LOAD TOOL
void mCore::LoadTool(wxString F)
{
    wxTextFile code;

    I[startToolPos+tNum].Clear();
    I[startToolPos+tNum].info = _("");

    if(code.Open(F))
    {
        if(code.GetFirstLine().Matches(_(".tool")))
        {
            while(!code.Eof())
            {
                wxString L = code.GetNextLine();
                E(L);
            }
        }

    }
}

//*******************************//
//**                           **//
//*******************************//
void mCore::SaveTool(wxString file)
{
    wxTextFile code(file);
    code.AddLine(_(".tool"));

    //images
    for(uint b=0; b<I[startToolPos+tNum].ME.size(); b++)
    {
        //LINE
        if(I[startToolPos+tNum].ME[b]->T()==1)
            code.AddLine( wxString::Format(_("t_l(%1.15f,%1.15f,%1.15f,%1.15f)"),

                                           I[startToolPos+tNum].ME[b]->p1().x,
                                           I[startToolPos+tNum].ME[b]->p1().y,
                                           I[startToolPos+tNum].ME[b]->p2().x,
                                           I[startToolPos+tNum].ME[b]->p2().y));
        //ARC
        if(I[startToolPos+tNum].ME[b]->T()==3)
            code.AddLine( wxString::Format(_("t_a(%1.15f,%1.15f,%1.15f,%1.15f,%1.15f)"),
                                           I[startToolPos+tNum].ME[b]->cp().x,
                                           I[startToolPos+tNum].ME[b]->cp().y,
                                           I[startToolPos+tNum].ME[b]->a1,
                                           I[startToolPos+tNum].ME[b]->a2,
                                           I[startToolPos+tNum].ME[b]->r));
        //circle
        if(I[startToolPos+tNum].ME[b]->T()==4)
            code.AddLine( wxString::Format(_("t_c(%1.15f,%1.15f,%1.15f)"),
                                           I[startToolPos+tNum].ME[b]->cp().x,
                                           I[startToolPos+tNum].ME[b]->cp().y,
                                           I[startToolPos+tNum].ME[b]->r));
    }

    //**************************************//
    //**** new way to make tool dta  *******//
    wxArrayString row = wxStringTokenize(I[startToolPos+tNum].info , wxT("\n"),wxTOKEN_STRTOK);
    for(uint b=0; row.Count()>b ; b++)
    {
        code.AddLine( wxString::Format(_("t_e(\"%s\")"),row[b].c_str() ));
    }

    code.Create();
    code.Write();
    code.Close();
}
void mCore::SetImageNumber(uint a)
{
    iNum = a;
};
void mCore::SetImageUp()
{
    iNum++;
    if(iNum==numImages)iNum=numImages-1;
};
void mCore::SetImageDown()
{
     iNum--;
     if(iNum<1)iNum=1;
};
//*************************//
//**       GLOBAL        **//
//*************************//
double ToDouble(wxString P)
{
    //P.Replace(_("."),_(","));
    double value;
    if(!P.ToDouble(&value))
    {
        return NAN;
    }
    return value;
};
